﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace AttrapeMoi
{
    class Voleur
    {
        private Vector2 position;
        private Vector2 ancienne_position;

        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }

        public Voleur(int x, int y)
        {
            position = new Vector2(x, y);
        }

        public void calculer_nouvelle_position(Carte carte)
        {
            int i = DirectionIntelligente(carte);
            if (i != -1)
            {
                carte.getCase(position).Contenu1 = Contenu.vide;
                position = carte.convertNumToXY(i);
                carte.getCase(position).Contenu1 = Contenu.voleur;
            }
        }

        /// <summary>
        /// lance le voleur dans une direction aleatoire
        /// </summary>
        /// <param name="carte">la carte sur laquelle le voleur se déplace</param>
        /// <returns>retourne le numéro de la prochaine case</returns>
        private int DirectionAleatoire(Carte carte)
        {
            List<int> liste_dir = new List<int>();
            int[,] matrice = carte.Matrice_adjacence;
            int numCase = carte.getCase(position.X, position.Y).NumCase;

            for (int i = 0; i < carte.Longueur_adjacence; i++)
            {
                if (matrice[i, numCase] == 1 && carte.getCase(ancienne_position).NumCase != i && carte.getCase(i).Contenu1 != Contenu.gendarme)
                    liste_dir.Add(i);
            }

            Random aleatoire = new Random();
            int a;
            do
            {
                a = aleatoire.Next(liste_dir.Count);
            } while (carte.getCase(liste_dir[a]).Contenu1 != Contenu.vide);

            return liste_dir[a];
        }

        /// <summary>
        /// lance le voleur sur la prochaine case la plus éloignée des gendarmes
        /// </summary>
        /// <param name="carte">le plateau de jeu</param>
        /// <returns>return le numéro de la case où aller</returns>
        public int DirectionIntelligente(Carte carte)
        {
            // voir quelle case autour de lui ou il peut aller est la plus loin des gendarmes

            List<Gendarme> liste_gend = carte.List_Gendarme;
            List<Sommet[,]> liste_color = new List<Sommet[,]>();

            foreach (Gendarme g in liste_gend)
            {
                liste_color.Add(Djikstra.Coloration(carte, g.Position));
            }

            List<Sommet> cases_adj = new List<Sommet>();

            int[,] matrice = carte.Matrice_adjacence;
            int numCase = carte.getCase(position.X, position.Y).NumCase;

            for (int i = 0; i < carte.Longueur_adjacence; i++)
            {
                if (matrice[i, numCase] == 1)
                {
                    Vector2 posCase = carte.convertNumToXY(i);
                    int minPotentiel = 10000;
                    foreach (Sommet[,] som in liste_color)
                    {
                        if (som[(int)posCase.Y, (int)posCase.X] != null && som[(int)posCase.Y, (int)posCase.X].Potentiel < minPotentiel)
                            minPotentiel = som[(int)posCase.Y, (int)posCase.X].Potentiel;
                    }
                    cases_adj.Add(new Sommet(minPotentiel, (int)posCase.X, (int)posCase.Y));
                }
            }
            // potentiel = distance ==> si grand alors gendarme loin
            int a = -1, max = 0;
            List<int> list_numCase = new List<int>();
            foreach (Sommet s in cases_adj)
            {
                if (s.Potentiel >= max)
                {
                    if (s.Potentiel > max)
                        list_numCase.Clear();

                    list_numCase.Add(carte.convertXYToNum(s.Pred.X, s.Pred.Y));

                    max = s.Potentiel;
                }
            }

            carte.CaseAdj = cases_adj;

            if (list_numCase.Count == 1)
                return list_numCase[0];
            else
            {
                int nbCaseAdjaMax = 0, i_final = -1;

                foreach (int i in list_numCase)
                {
                    int nbCaseAdja = 0;
                    for (int j = 0; j < carte.Longueur_adjacence; j++)
                    {
                        if (matrice[j, i] == 1)
                            nbCaseAdja++;
                    }

                    if (nbCaseAdjaMax < nbCaseAdja)
                    {
                        nbCaseAdjaMax = nbCaseAdja;
                        i_final = i;
                    }
                }

                return i_final;
            }
        }
    }
}
